home *** CD-ROM | disk | FTP | other *** search
/ Fritz: All Fritz / All Fritz.zip / All Fritz / FILES / PROGSCAL / TURBOK50.LZH / SOURCE.ARC / DIRTTT5.PAS < prev    next >
Pascal/Delphi Source File  |  1989-05-24  |  54KB  |  1,613 lines

  1. {--------------------------------------------------------------------------}
  2. {                         TechnoJock's Turbo Toolkit                       }
  3. {                                                                          }
  4. {                              Version   5.01A                             }
  5. {                                                                          }
  6. {                                                                          }
  7. {              Copyright 1986, 1989 TechnoJock Software, Inc.              }
  8. {                           All Rights Reserved                            }
  9. {                          Restricted by License                           }
  10. {--------------------------------------------------------------------------}
  11.  
  12.                      {--------------------------------}
  13.                      {       Unit:   DirTTT5          }
  14.                      {--------------------------------}
  15.  
  16.  
  17. {$S-,R-,V-}
  18. {$IFNDEF DEBUG}
  19. {$D-}
  20. {$ENDIF}
  21.  
  22.  
  23. unit  DirTTT5;
  24.  
  25. {Change History:    04/01/89  Changed logic if no file found and DIRFULL
  26.                               is false - Line 1174
  27.              5.01A  05/18/89  Added line to allow only directores to be displayed.
  28.                               Line 923
  29. }
  30.  
  31. (*
  32. {$DEFINE DIRFULL}
  33. *)
  34.  
  35. INTERFACE
  36.  
  37. Uses DOS,CRT,FastTTT5,WinTTT5,StrnTTT5,KeyTTT5,ReadTTT5;
  38.  
  39. Const
  40.    DHelpKey = #187;                     {Alter these keys if desired.       }
  41.    DHelpStr:string[2] = 'F1';           {Note: to disable these keys, set   }
  42.    DToggleKey = #32;                    {      appropriate flags in Var D.   }
  43.    DToggleStr: string[5] = 'Space';
  44.    DZoomKey = #172;
  45. {$IFDEF DIRFULL}
  46.    DZoomStr: string[5] = 'Alt-Z';
  47.    DJumpParentKey = #176;
  48.    DJumpParentStr: string[5] = 'Alt-B';
  49.    DChangeDirKey = #174;
  50.    DChangeDirStr: string[5] = 'Alt-C';
  51.    DSortOrderKey = #152;
  52.    DSortOrderStr: string[5] = 'Alt-O';
  53.    DSortSizeKey = #159;
  54.    DSortSizeStr: string[5] = 'Alt-S';
  55.    DSortNameKey = #177;
  56.    DSortNameStr: string[5] = 'Alt-N';
  57.    DSortExtKey = #146;
  58.    DSortExtStr: string[5] = 'Alt-E';
  59.    DSortTimeKey = #148;
  60.    DSortTimeStr: string[5] = 'Alt-T';
  61.    DSortDOSKey = #160;
  62.    DSortDOSStr: string[5] = 'Alt-D';
  63.    DSortDos  = 1;
  64.    DSortName = 2;
  65.    DSortExt  = 3;
  66.    DSortSize = 4;
  67.    DSortTime = 5;
  68.    Ascending = 1;
  69.    Descending = 2;
  70. {$ENDIF}
  71.  
  72. Type
  73.    DirDisplay = record
  74.                      TopX       : byte;
  75.                      TopY       : Byte;
  76.                      Rows       : byte;
  77.                      Attrib     : byte;
  78.                      BoxType    : byte;
  79.                      BoxFCol    : byte;
  80.                      BoxBCol    : byte;
  81.                      KeyFCol    : byte;
  82.                      BacCol     : byte;
  83.                      NorFCol    : byte;
  84.                      DirFCol    : byte;
  85.                      HiFCol     : byte;
  86.                      HiBCol     : byte;
  87.                      AllowEsc   : boolean;
  88.                      ShowDetails: boolean;
  89.                      Colswide   : byte;
  90.                      DisplayInfo: boolean;
  91.                      RestoreScreen : boolean;
  92.                      AllowHelp     : boolean;
  93.                      AllowToggle   : boolean;
  94.                      AllowZoom     : boolean;
  95.                      ZoomLine      : byte;
  96.                      AllowSort     : boolean;
  97.                      InitSort      : byte;
  98.                      Asc           : byte;
  99.                      AllowCD       : boolean;
  100.                      SelectDir     : boolean;
  101.                      AllowInput    : boolean;
  102.                  end;
  103.  
  104. Var
  105.    DTTT : DirDisplay;
  106.    NoMemory : boolean;
  107.  
  108. Function Display_Directory(DIRFULLFileName: StrScreen;var Retcode:integer): StrScreen;
  109. Procedure Default_Settings;
  110.  
  111. IMPLEMENTATION
  112.  
  113.   
  114. Procedure Default_Settings;
  115. begin
  116.     With  DTTT  do
  117.     begin
  118.         TopX    := 0;
  119.         TopY    := 0;
  120.         Rows    := 0;
  121.         AllowEsc := true;
  122.         Attrib := Readonly + Directory + Archive;
  123.         BoxType := 1;
  124.         ShowDetails := true;
  125.         ColsWide := 5;
  126. {$IFDEF DIRFULL}
  127.         DisplayInfo := true;
  128.         AllowHelp := true;
  129.         AllowZoom   := true;
  130.         ZoomLine := 25;
  131.         AllowSort := true;
  132.         InitSort := DSortDOS;     {sort in DOS order}
  133.         AllowInput := True;
  134. {$ELSE}
  135.         DisplayInfo := false;
  136. {$ENDIF}
  137.         AllowCD := true;
  138.         SelectDir := false;
  139.         RestoreSCreen := true;
  140.         AllowToggle := true;
  141.         Asc := 1;
  142.         If BaseOfScreen = $b000 then
  143.         begin
  144.             BoxFCol := white;
  145.             BoxBCol := black;
  146.             KeyFCol := white;
  147.             BacCol := black;
  148.             NorFCol := white;
  149.             DirFCol := lightgray;
  150.             HiFcol := black;
  151.             HiBcol := lightgray
  152.         end
  153.         else
  154.         begin
  155.             BoxFCol := lightgray;
  156.             BoxBCol := blue;
  157.             KeyFCol := yellow;
  158.             BacCol := black;
  159.             NorFCol := white;
  160.             DirFCol := yellow;
  161.             HiFcol := black;
  162.             HiBcol := cyan;
  163.         end;
  164.     end; {with}
  165. end;
  166.  
  167.  
  168.  
  169. Function Display_Directory( DIRFULLFilename: StrScreen; var Retcode : integer): StrScreen;
  170. {
  171.               X1                                    X2
  172.      Y1 >      _____________________________________
  173.               |                                     | >
  174.               |                                     | >  Infodepth
  175.               |                                     | >
  176.      Y2 >     |_____________________________________| >
  177.               |                                     |
  178.               |                                     |
  179.               |                                     |
  180.               |                                     |
  181.               |                                     |
  182.               |                                     |
  183.      Y3 >     |_____________________________________|
  184.  
  185.  
  186.           Retcodes >    0  -  filechosen
  187.                         1  -  user escaped
  188.                         2  -  not enough memory
  189.                         3  -  no files matching
  190.                         99 -  unexpected error
  191.  
  192. }
  193. Type
  194.   FRptr = ^FR;
  195.   FR = record
  196.             Name : string[8];
  197.             Ext  : string[3];
  198.             Size : longint;
  199.             Time : longint;
  200.             Attr : byte;
  201.             Fn : integer;
  202.             PrevFR: FRptr;
  203.             NextFR : FRptr;
  204.        end;
  205.  
  206. const
  207.   OKCode = 0;           {ret codes}
  208.   EscCode = 1;
  209.   MemCode = 2;
  210.   NofilesCode = 3;
  211.   UnKnownCode = 99;
  212.   InfoDepth = 4;        {no of lines in information box, i.e.Y1 to Y2}
  213.   ReadMsg = 'Reading files';
  214.   SortMsg = 'Sorting files';
  215.   NoneMsg = 'No files ... ';
  216. var
  217.   X1,X2,Y1,Y2,Y3,R,Y3_Unzoomed : byte;{box dimensions}
  218.   StartDir : StrScreen;      {default directory}
  219.   ColumnsWide : byte;
  220.   TopFn : integer;           {file number of top file in the display}
  221.   BotFn : integer;           {file number of bottom file in the display}
  222.   HiFn  : integer;           {file number of hilighted file}
  223.   Zoomed: boolean;           {is file display extended to bottom of screen}
  224.   ShowingDetails : boolean;
  225.   PathName : StrScreen;      {the path section of filename}
  226.   FileMask : StrScreen;
  227.   FirstFile : FRptr;
  228.   List_End : FRptr;
  229.   ChosenFile: strscreen;
  230.   TotalFiles: word;
  231.   TotalDirs : word;
  232.   TotalBytes: LongInt;
  233.   Ftemp : FRPtr;
  234.   HeapTop : pointer;
  235.   DirTop : pointer;
  236.   Scrn : pointer;
  237.   CursRec : array[1..4] of byte;
  238.   SortOrder : byte;               {1-DOS, 2-Name, 3-Ext, 4-Size, 5-Time}
  239.   SortAsc : boolean;
  240.  
  241.     Function Subdirectory(B : byte):boolean;
  242.     begin
  243.         Subdirectory := ((B and Directory) = Directory);
  244.     end;
  245.  
  246.     Function FileAttribs(B:byte):StrScreen;
  247.     var
  248.       S : StrScreen;
  249.     begin
  250.         S := '    ';
  251.         If ((B and ReadOnly) = Readonly) then
  252.            S[1] := 'R';
  253.         If ((B and Hidden) = Hidden) then
  254.            S[2] := 'H';
  255.         If ((B and SysFile) = SysFile) then
  256.            S[3] := 'S';
  257.         If ((B and Archive) = Archive) then
  258.            S[4] := 'A';
  259.         FileAttribs := S;
  260.      end;
  261.  
  262.      Function LongFileDesc(F:FRptr):StrScreen;
  263.      var
  264.        DT :datetime;
  265.        S  : StrScreen;
  266.      begin
  267.          If ShowingDetails then
  268.          begin
  269.              with F^ do
  270.              begin
  271.                  UnPackTime(Time,DT);
  272.                  With DT do
  273.                  begin
  274.                      If Ext = '' then
  275.                         S := Padleft(Name,12,' ')
  276.                      else
  277.                         S :=  Padleft(Name+'.'+Ext,12,' ');                 {start with name}
  278.                      If Subdirectory(Attr) then                  {add file size}
  279.                         S := S + Padright('<DIR>',8,' ')
  280.                      else
  281.                         S := S + Padright(Int_to_Str(Size),8,' ');
  282.                      S := S + '    ';
  283.                      Case Month of                               {add month}
  284.                      1 : S := S + 'Jan ';
  285.                      2 : S := S + 'Feb ';
  286.                      3 : S := S + 'Mar ';
  287.                      4 : S := S + 'Apr ';
  288.                      5 : S := S + 'May ';
  289.                      6 : S := S + 'Jun ';
  290.                      7 : S := S + 'Jul ';
  291.                      8 : S := S + 'Aug ';
  292.                      9 : S := S + 'Sep ';
  293.                      10: S := S + 'Oct ';
  294.                      11: S := S + 'Nov ';
  295.                      12: S := S + 'Dec ';
  296.                      end;
  297.                      S :=   S                                   {add the day,year}
  298.                           + Padright(Int_to_Str(Day),2,'0')
  299.                           + ','
  300.                           + Int_to_Str(Year)
  301.                           + '    ';
  302.                      If Hour > 12 then                          {add a/p time}
  303.                         S :=  S
  304.                              +Padright(Int_to_Str(Hour-12),2,' ')
  305.                              +':'
  306.                              +Padright(Int_to_Str(Min),2,'0')
  307.                              +'p'
  308.                      else
  309.                         S :=  S
  310.                               +Padright(Int_to_Str(Hour),2,' ')
  311.                               +':'
  312.                               +Padright(Int_to_Str(Min),2,'0')
  313.                               +'a';
  314.                         S := S + '  '+FileAttribs(Attr);
  315.                  end;   {with DT}
  316.              end; {with F^}
  317.          end
  318.          else    {not one column}
  319.           If F^.Ext = '' then
  320.              S := Padleft(F^.Name,12,' ')
  321.           else
  322.              S := Padleft(F^.Name+'.'+F^.Ext,12,' ');
  323.          LongFileDesc := S;
  324.      end;
  325.  
  326.     Function PathSlash(S : StrScreen):StrScreen;
  327.     begin
  328.         If S[length(S)] <> '\' then
  329.            S := S + '\';
  330.         PathSlash := S;
  331.     end;  {Sub Func PathSlash}
  332.  
  333.     Function PathNoSlash(S : StrScreen):StrScreen;
  334.     begin
  335.         If S[length(S)] = '\' then
  336.            Delete(S,length(S),1);
  337.         PathNoSlash := S;
  338.     end;  {Sub Func PathSlash}
  339.  
  340.     Function PathParent(S : StrScreen):StrScreen;
  341.     var P1 : byte;
  342.     begin
  343.         S := PathNoSlash(S);
  344.         P1 := LastPos('\',S);
  345.         PathParent := copy(S,1,P1);
  346.     end;
  347.  
  348.     Function PathChild(S : StrScreen):StrScreen;
  349.     begin
  350.         PathChild := PathSlash(PathName + S);
  351.     end;
  352.  
  353.     Procedure Extract_Path_Mask;
  354.     var P1,P2 : byte;
  355.     begin
  356.         P1 := LastPos('\',DIRFULLFileName);
  357.         P2 := Pos(':',DIRFULLFilename);
  358.         If (P1 = 0) and (P2 = 0) then
  359.         begin
  360.             FileMask := DIRFULLFileName;
  361.             PathName := PathSlash(StartDir);
  362.             exit;
  363.         end;
  364.         If P1 = length(DIRFULLFileName) then
  365.         begin
  366.             FileMask := '*.*';
  367.             PathName := DIRFULLFileName;
  368.             exit;
  369.         end;
  370.         If (P1 = 0) and (P2 = 2) then   { x:filename.ext}
  371.         begin
  372.            Filemask := copy(DIRFULLFileName,3,length(DIRFULLFileName));
  373.            {$I-}
  374.            GetDir(ord(upcase(DIRFULLFileName[1]))-64,PathName);
  375.            {$I-}
  376.            If IOResult <> 0 then
  377.               PathName := PathSlash(StartDir)
  378.            else
  379.               PathName := PathSlash(PathName);
  380.            exit;
  381.         end;
  382.         Filemask := copy(DIRFULLFileName,succ(P1),12);
  383.         PathName := copy(DIRFULLFileName,1,P1);
  384.     end;  {Extract_Path_Mask}
  385.  
  386.     Procedure LoadFiles(Mask:StrScreen;Attrib:byte);
  387.     var
  388.       Finfo : SearchRec;
  389.       Recsize : word;
  390.  
  391.       Procedure PushOnHeap(var F:FrPtr);
  392.       var P : byte;
  393.       begin
  394.           with F^ do
  395.           begin
  396.               Attr := Finfo.Attr;
  397.               Time := Finfo.Time;
  398.               Size := Finfo.Size;
  399.               If FInfo.Name = '..' then
  400.               begin
  401.                   Name := '..';
  402.                   Ext := '';
  403.               end
  404.               else
  405.               begin
  406.                   P := pos('.',Finfo.Name);
  407.                   If P = 0 then
  408.                   begin
  409.                       Name := Finfo.Name;
  410.                       Ext := '';
  411.                  end
  412.                  else
  413.                  begin
  414.                      Name := copy(FInfo.Name,1, pred(P));
  415.                      Ext := copy(Finfo.Name,succ(P),3);
  416.                  end;
  417.               end;
  418.               Fn := succ(TotalFiles);
  419.               NextFR := nil;
  420.               PrevFr := nil;
  421.               TotalBytes := TotalBytes + Size;
  422.           end;
  423.           Inc(TotalFiles);
  424.           If Finfo.Attr = Directory then
  425.              Inc(TotalDirs);
  426.       end;   {sub sub proc TransferFileToHeap}
  427.  
  428.       Procedure AllocHeap;
  429.       begin
  430.           If ( (Attrib = Directory) and (FInfo.Attr <> Directory) ) then
  431.              exit;   {if only looking for directory entries}
  432.           If (Finfo.Name <> '.') and (DosError = 0) then
  433.           begin
  434.               If (TotalFiles = 0) then
  435.               begin
  436.                   PushOnHeap(FirstFile);
  437.                   FirstFile^.PrevFR := nil;
  438.                   Ftemp :=  FirstFile;
  439.                   List_End := FirstFile;
  440.               end
  441.               else
  442.               begin
  443.                   GetMem(Ftemp^.NextFR,Recsize);
  444.                   PushOnHeap(FTemp^.NextFr);
  445.                   FTemp := Ftemp^.NextFR;
  446.                   FTemp^.PrevFR := List_End;
  447.                   List_End := Ftemp;
  448.               end; {If TotalFiles = 0}
  449.          end; { If name <> '.'}
  450.       end;
  451.  
  452.     begin
  453.         RecSize := Sizeof(FirstFile^);
  454.         If MaxAvail < 2*Recsize then
  455.         begin
  456.             NoMemory := true;
  457.             exit;
  458.         end;
  459.         Fastwrite(X1+2,Y2+1,attr(DTTT.NorFcol+blink,DTTT.BacCol),ReadMsg);
  460.         FindFirst(PathName+Mask,Attrib,Finfo);
  461.         If DosError <> 0 then
  462.            exit;
  463.         If TotalFiles = 0 then
  464.         begin
  465.            GetMem(FirstFile,RecSize);
  466.            GetMem(List_End,RecSize);
  467.         end;
  468.         AllocHeap;
  469.         While (DosError = 0) and (NoMemory = false) do
  470.         begin
  471.             If MaxAvail < RecSize then
  472.                NoMemory := true
  473.             else
  474.             begin
  475.                 FindNext(Finfo);
  476.                 AllocHeap;
  477.             end; {If MaxAvail}
  478.         end; {while}
  479.     end; {Sub Proc Loadfiles}
  480.  
  481.     Procedure Calculate_Box_Dimensions;
  482.     var
  483.       Boxwidth : byte;
  484.     begin
  485.         If ShowingDetails then
  486.            Boxwidth := 54
  487.         else
  488.            Boxwidth := succ(DTTT.Colswide*14);
  489.         with DTTT do
  490.         begin
  491.             If (TopX < 1) or (TopX > 80) then
  492.                X1 :=  (80 - Boxwidth) div 2
  493.             else
  494.             begin
  495.                If TopX <= (80 - Boxwidth) then
  496.                   X1 := TopX
  497.                else                               {move box left until it fits}
  498.                   X1 := 80 - Boxwidth;
  499.             end;
  500.             X2 := X1 + Boxwidth;
  501.             If Rows in [1..23] then
  502.                R := Rows
  503.             else
  504.                R := 8;
  505.             If (TopY < 1) or (TopY > DisplayLines - 2) then
  506.                Y1 := 5
  507.             else
  508.                Y1 := TopY;
  509.             If not DisplayInfo then
  510.                Y2 := Y1
  511.             else
  512.             begin
  513.                 If Y1 + InfoDepth < DisplayLines - 2 then
  514.                    Y2 := Y1 + InfoDepth
  515.                 else                               {no room for info}
  516.                    Y2 := Y1;
  517.             end;
  518.             Y3 := Y2 + succ(R);
  519.             If Y3 > DisplayLines then
  520.             begin
  521.                Y3 := DisplayLines;
  522.                If Y2 <> Y1 then
  523.                begin
  524.                    Y2 := Y3 - succ(R);
  525.                    Y1 := Y2 - InfoDepth;
  526.                end
  527.                else
  528.                begin
  529.                    Y2 := Y3 - succ(R);
  530.                    Y1 := Y2;
  531.                end;
  532.             end;
  533.         end;
  534.     end;  {sub proc Calculate_Box_Dimensions}
  535.  
  536.     Procedure Display_Box;
  537.     var
  538.       LChar,Rchar : char;
  539.       Col,
  540.       I : integer;
  541.     begin
  542.         with DTTT do
  543.         begin
  544.             If Y2 = Y1 then
  545.                ClearText(X1,Y1,X2,Y3,NorFCol,Baccol)
  546.             else
  547.             begin
  548.                 ClearText(X1,Y1,X2,pred(Y2),BoxFCol,BoxBcol);
  549.                 ClearText(X1,Y2,X2,Y3,NorFCol,Baccol);
  550.             end;
  551.             Col := attr(BoxFcol,BoxBCol);
  552.             If (BoxType in [5..9]) then
  553.             begin
  554.                 Box(X1,Y1,X2,Y3,BoxFcol,BoxBcol,Boxtype-5);
  555.                 If (X2 < 80) and (Y3 < DisplayLines) then
  556.                 begin
  557.                     For I := succ(Y1) to succ(Y3) do
  558.                         Fastwrite(succ(X2),I,ShadColor,chr(219));
  559.                     Fastwrite(succ(X1),succ(Y3),ShadColor,replicate(X2-X1,chr(219)));
  560.                 end;
  561.             end
  562.             else
  563.                Box(X1,Y1,X2,Y3,BoxFcol,BoxBcol,Boxtype);
  564.             If Y2 > Y1 then
  565.             begin
  566.                 Horizline(succ(X1),pred(X2),Y2,BoxFCol,BoxBcol,Boxtype);
  567.                 Case Boxtype of
  568.                 1,6 : begin
  569.                           LChar := chr(195);
  570.                           RChar := chr(180);
  571.                       end;
  572.                 2,7 : begin
  573.                           LChar := chr(204);
  574.                           RChar := chr(185);
  575.                       end;
  576.                 3,8 : begin
  577.                           LChar := chr(199);
  578.                           RChar := chr(182);
  579.                       end;
  580.                 4,9 : begin
  581.                           LChar := chr(181);
  582.                           RChar := chr(198);
  583.                       end;
  584.                 else      Lchar := ' ';
  585.                           Rchar := ' ';
  586.                 end;  {case}
  587.                 Fastwrite(X1,Y2,Col,Lchar);
  588.                 Fastwrite(X2,Y2,Col,Rchar);
  589.             end;
  590.         end;
  591.     end;  {sub proc display box}
  592.  
  593.     Procedure DisplayPath;
  594.     var
  595.        L : byte;
  596.        Y : byte;
  597.        P : StrScreen;
  598.     begin
  599.         P := Pathname+Filemask;
  600.         L := length(P);
  601.         If Y2 = Y1 then
  602.         begin
  603.            Y := Y1;
  604.            If L > (X2-X1-2) then
  605.               P := chr(17)+copy(P,L-(X2-X1)+4,L);
  606.         end
  607.         else
  608.         begin
  609.            Y := Y1 + 2;
  610.            If L > (X2-X1-2) then
  611.               P := chr(17)+copy(P,L-(X2-X1-1)+4,L);
  612.         end;
  613.         Fastwrite(X1+2,Y,attr(DTTT.BoxFcol,DTTT.BoxBCol),P);
  614.     end;  {sub Proc DisplayPath}
  615.  
  616.  
  617.     Procedure FillInfo;
  618.     var
  619.       TB,Di : StrScreen;
  620.       C,H,L  : byte;
  621.     begin
  622.         with DTTT do
  623.         begin
  624.             C := attr(BoxFCol,BoxBCol);
  625.             H := attr(KeyFcol,BoxBCol);
  626.             If (Y2 = Y1) then
  627.             begin
  628.                 DisplayPath;
  629.                 exit;
  630.             end;
  631. {$IFDEF DIRFULL}
  632.             If  (ColumnsWide < 3 ) and (ShowingDetails = false) then
  633.             begin
  634.                 DisplayPath;
  635.                 Fastwrite(X1+2,Y1+1,H,chr(17)+char(217));
  636.                 Fastwrite(X1+5,Y1+1,C,'Select');
  637.                 Fastwrite(X1+2,Y1+3,C,'Files: ');
  638.                 Fastwrite(X1+9,Y1+3,C,Int_To_Str(TotalFiles-TotalDirs));
  639.                 exit;
  640.             end;
  641.             ClearText(succ(X1),Succ(Y1),pred(X2),Pred(Y2),BoxFcol,BoxBCol);
  642.             Fastwrite(X1 + 2,Y1 + 3,C,'Matching files: ');
  643.             Fastwrite(X1 + 18,Y1 + 3,C,Int_To_Str(TotalFiles-TotalDirs));
  644.             TB := 'Total bytes: '+Int_To_Str(TotalBytes);
  645.             Fastwrite(X2 -length(TB) - 1,Y1 + 3,C,TB);
  646.             If AllowHelp then
  647.             begin
  648.                 Fastwrite(X1+2,Y1+1,H,DHelpStr);    {Prompt at left}
  649.                 Fastwrite(X1+3+length(DHelpStr),Y1+1,C,'Help');
  650.             end;
  651.             L := pred(X1)
  652.                + ((X2-X1) div 2)
  653.                - (length(DToggleStr)+ 7) div 2;     {next prompt in center}
  654.             Fastwrite(L,Y1+1,H,chr(17)+char(217));
  655.             L := L + 3;
  656.             Fastwrite(L,Y1+1,C,'Select');
  657.             If AllowToggle then
  658.             begin
  659.                 L := X2 - length(DToggleStr) - 8;   {right justified}
  660.                 Fastwrite(L,Y1+1,H,DToggleStr);
  661.                 L := L + 1 + length(DToggleStr);
  662.                 Fastwrite(L,Y1+1,C,'Toggle');
  663.             end;
  664.         end;
  665.         DisplayPath;
  666. {$ELSE}
  667.        end;
  668. {$ENDIF}
  669.     end;  {sub proc Fillinfo}
  670.  
  671.     Function FilePointer(Fn:word): FRptr;
  672.     {MODIFY to go from current pointer - for speed}
  673.     var
  674.       P : FRptr;
  675.       I : integer;
  676.     begin
  677.         If  SortAsc then
  678.         begin
  679.             P := FirstFile;
  680.             If Fn > 1 then
  681.                For I := 2 to Fn do
  682.                    P := P^.NextFr;
  683.         end
  684.         else {Descending}
  685.         begin
  686.             P := List_End;
  687.             If Fn > 1 then
  688.                For I := 2 to Fn do
  689.                    P := P^.PrevFr;
  690.         end;
  691.         FilePointer := P;
  692.     end;  {sub proc filepointer}
  693.  
  694.     Function Y_Coord(Fn : word):byte;
  695.     begin
  696.          Y_Coord := Succ(Y2) + ((Fn-TopFn) DIV ColumnsWide);
  697.     end;
  698.  
  699.     Function X_Coord(Fn : word):byte;
  700.     begin
  701.            X_Coord := succ(X1) + 14*((Fn-TopFn) MOD Columnswide);
  702.     end;
  703.  
  704.     Function TopLine:Boolean;
  705.     begin
  706.           TopLine := (HiFn <= ColumnsWide);
  707.     end;
  708.  
  709.     Function BottomLine:Boolean;
  710.     begin
  711.           BottomLine := (HiFn + ColumnsWide > TotalFiles);
  712.     end;
  713.  
  714.     Function FirstColumn:boolean;
  715.     begin
  716.            If Columnswide = 1 then
  717.               FirstColumn := true
  718.            else
  719.               FirstColumn := (HiFn MOD ColumnsWide = 1);
  720.     end;
  721.  
  722.     Function LastColumn:boolean;
  723.     begin
  724.            LastColumn := (HiFn MOD ColumnsWide = 0);
  725.     end;
  726.  
  727.     Procedure RecalcTopFn;
  728.     begin
  729.         If ColumnsWide = 1 then
  730.            TopFn := succ(BotFn -R)
  731.         else
  732.             TopFn :=  Succ(   BotFn
  733.                             - pred(R)*ColumnsWide
  734.                             - BotFn MOD ColumnsWide
  735.                           );
  736.     end;
  737.  
  738.     Procedure RecalcBotFn;
  739.     begin
  740.         BotFn := pred( TopFn + ColumnsWide*R);
  741.         If BotFn > TotalFiles then
  742.            BotFn := TotalFiles;
  743.     end;
  744.  
  745.     Procedure LolightFile(Fn:word);
  746.     var
  747.       C : byte;
  748.       F : FRptr;
  749.     begin
  750.         If (Fn < TopFn) or (Fn > BotFn ) then
  751.            exit;    {file not in display area}
  752.         F := Filepointer(Fn);
  753.         If Subdirectory(F^.Attr) then
  754.            C := attr(DTTT.DirFcol,DTTT.BacCol)
  755.         else
  756.            C := attr(DTTT.NorFCol,DTTT.BacCol);
  757.         Fastwrite(X_Coord(Fn),
  758.                   Y_Coord(Fn),
  759.                   C,
  760.                   ' '+LongFileDesc(F)+' ');
  761.     end;
  762.  
  763.     Procedure HilightFile(Fn:word);
  764.     var
  765.       F : FRptr;
  766.     begin
  767.         If (Fn < TopFn) or (Fn > BotFn) then
  768.            exit;    {file not in display area}
  769.         F := Filepointer(Fn);
  770.         Fastwrite(X_Coord(Fn),
  771.                   Y_Coord(Fn),
  772.                   attr(DTTT.HiFcol,DTTT.HiBCol),
  773.                   +' '+LongFileDesc(F)+' ')
  774.     end;
  775.  
  776.     Function File_name(Fn : word):StrScreen;
  777.     var
  778.        F : FRPtr;
  779.        Fname : strscreen;
  780.     begin
  781.         F := FilePointer(Fn);
  782.         Fname := F^.Name;
  783.         If F^.Ext <> '' then
  784.            Fname := Fname+'.'+F^.Ext;
  785.         File_Name := Fname;
  786.     end;   {Sub Funct File_name}
  787.  
  788.     Procedure DisplayFiles;
  789.     var
  790.       I : integer;
  791.     begin
  792.         If (Columnswide > 1) and (BotFn = TotalFiles) then    {clear line}
  793.            ClearText(succ(X1),pred(Y3),Pred(X2),pred(Y3),DTTT.NorFcol,DTTT.BacCol);
  794.         For I := TopFn to BotFn do
  795.             If (I <> HiFn) and (I <= TotalFiles) then
  796.                LolightFile(I);
  797.         HiLightFile(HiFn);
  798.     end; {sub proc DisplayFiles}
  799.  
  800.     Procedure Scroll_Down;
  801.     begin
  802.         TopFn := TopFn + Columnswide;
  803.         RecalcBotFn;
  804.         DisplayFiles;
  805.     end; {scroll_down}
  806.  
  807.     Procedure Scroll_Up;
  808.     begin
  809.         TopFn := TopFn - Columnswide;
  810.         RecalcBotFn;
  811.         DisplayFiles;
  812.     end; {scroll_up}
  813.  
  814.     Procedure Scroll_Top;
  815.     begin
  816.         TopFn := 1;
  817.         RecalcBotFn;
  818.         HiFn := 1;
  819.         DisplayFiles;
  820.     end; {scroll_Home}
  821.  
  822.     Procedure Scroll_Bottom;
  823.     begin
  824.         TopFn := succ(TotalFiles - R);
  825.         BotFn := TotalFiles;
  826.         HiFn := TotalFiles;
  827.         DisplayFiles;
  828.     end; {scroll_Home}
  829.  
  830.  
  831. {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\    SORTING   \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\}
  832. {$IFDEF DIRFULL}
  833.  
  834. Function Larger(Ptr1,Ptr2: FRptr) : boolean;
  835. var
  836.    N1,N2 : string[8];
  837.    E1,E2 : string[8];
  838. begin
  839.     Case SortOrder of
  840.     DSortDos   : Larger := (Ptr1^.Fn > Ptr2^.Fn);
  841.     DSortNAME  : If Ptr1^.Name = Ptr2^.Name then
  842.                     Larger := Ptr1^.Ext > Ptr2^.Ext
  843.                  else
  844.                     Larger := Ptr1^.Name > Ptr2^.Name;
  845.     DSortEXT   : If Ptr1^.Ext = Ptr2^.Ext then
  846.                     Larger := Ptr1^.Name > Ptr2^.Name
  847.                  else
  848.                     Larger := Ptr1^.Ext > Ptr2^.Ext;
  849.     DSortSIZE  : Larger := (Ptr1^.Size > Ptr2^.Size);
  850.     DSortTIME  : Larger := (Ptr1^.Time > Ptr2^.Time);
  851.     else Larger := false;
  852.     end; {Case}
  853. end; {suc proc larger}
  854.  
  855. Procedure SwapIt(var Ptr1,Ptr2: FRPtr);
  856. var
  857.    Temp : FR;
  858.    Size : integer;
  859. begin
  860.     Temp := Ptr2^;
  861.     Size := sizeof(Temp) - 8;
  862.     Move(Ptr1^,Ptr2^,Size);
  863.     Move(Temp,Ptr1^,Size);
  864. end;  {sub proc Swap}
  865.  
  866. Procedure ShellSort;
  867. var
  868.    I,J,Delta : longint;
  869.    Swapped : boolean;
  870.    Ptr1,Ptr2 : FRPtr;
  871.  
  872. begin
  873.     Delta := TotalFiles div 2;
  874.     repeat
  875.          Repeat
  876.               Swapped := false;
  877.               Ptr1 := FirstFile;
  878.               Ptr2 := Ptr1;
  879.               For I := 1 to Delta do
  880.                   Ptr2 := Ptr2^.NextFr;
  881.               For I := 1 to TotalFiles - Delta do
  882.               begin
  883.                   If I > 1 then
  884.                   begin
  885.                       Ptr1 := Ptr1^.NextFr;
  886.                       Ptr2 := Ptr2^.NextFr;
  887.                   end;
  888.                   If Larger(Ptr1,Ptr2) then
  889.                   begin
  890.                       SwapIt(Ptr1,Ptr2);
  891.                       Swapped := true;
  892.                   end;
  893.               end;
  894.          Until (not Swapped);
  895.          Delta := delta div 2;
  896.     Until Delta = 0;
  897. end;
  898.  
  899.                 Procedure ReSort;
  900.                 begin
  901.                     ClearText(succ(X1),Succ(Y2),pred(X2),pred(Y3),DTTT.NorFcol,DTTT.BacCol);
  902.                     Fastwrite(X1 + 2,succ(Y2),attr(DTTT.NorFcol+blink,DTTT.BacCol),SortMsg);
  903.                     ShellSort;
  904.                     TopFn := 1;
  905.                     HiFn := 1;
  906.                     RecalcBotFn;
  907.                     DisplayFiles;
  908.                 end;
  909. {$ENDIF}
  910.  
  911.     Procedure DisplayNewDirectory;
  912.     var A : byte;
  913.     begin
  914.         A := DTTT.attrib and (AnyFile - VolumeID);
  915.         Display_Box;
  916.         TotalFiles := 0;
  917.         TotalBytes := 0;
  918.         TotalDirs  := 0;
  919.         Mark(DirTop);
  920.         If DTTT.AllowCd or DTTT.SelectDir then
  921.         begin
  922.             If Subdirectory(A) then
  923.             begin
  924.                  LoadFiles('*.*',Directory);                {load directory details first}
  925.                  If A <> Directory then                     {Fix 5.01A}
  926.                     Loadfiles(Filemask,A and (anyfile - Directory));  {then load other files with mask}
  927.             end
  928.             else
  929.                  LoadFiles(Filemask,A and (Anyfile - Directory));
  930.         end
  931.         else                  {automatically removed directory type files}
  932.              LoadFiles(Filemask,A and (anyfile - Directory));
  933.         FillInfo;
  934. {$IFDEF DIRFULL}
  935.         If SortOrder <> DSortDOS then
  936.            ShellSort;
  937. {$ENDIF}
  938.         If TotalFiles = 0 then
  939.            Fastwrite(X1+2,Y2+1,attr(DTTT.NorFcol,DTTT.BacCol),NoneMsg)
  940.         else
  941.            Scroll_Top;
  942.     end;  {sub proc DisplayNewDirectory}
  943.  
  944. {$IFDEF DIRFULL}
  945.     Procedure ShowHelpScreen;
  946.     const
  947.         width = 55;
  948.         depth = 14;
  949.     var
  950.       Str : StrScreen;
  951.       S  : word;
  952.       Sc : pointer;
  953.       X,Y : byte;
  954.       ChH : char;
  955.     begin
  956.         If X1 + width > 80 then
  957.            X := pred((80 - width) div 2)
  958.         else
  959.            X := X1;
  960.         If Y1 + Depth > DisplayLines then
  961.            Y := pred((DisplayLines -Depth) div 2)
  962.         else
  963.            Y := Y1;
  964.         S := 160*DisplayLines;
  965.         If MaxAvail < S then
  966.            exit;
  967.         GetMem(Sc,S);
  968.         MoveFromScreen(Mem[BaseOfScreen:0],Sc^,S Div 2);
  969.         FBox(X,Y,pred(X+ width),pred(Y+Depth),DTTT.BoxFCol,DTTT.BoxBCol,1);
  970.         Case SortOrder of
  971.         DSortDos  : Str := ' DOS';
  972.         DSortName : Str := ' NAME';
  973.         DSortExt  : Str := ' EXT';
  974.         DSortSize : Str := ' SIZE';
  975.         DSortTime : Str := ' TIME';
  976.         end; {case}
  977.         If SortAsc then
  978.            Str := Str +' in ASCENDING order'
  979.         else
  980.            Str := Str +' in DESCENDING order';
  981.         If Zoomed then
  982.            Str := Str +' (Zoomed) '
  983.         else
  984.            Str := Str+' (not zoomed) ';
  985.         Str := ' Current: '+Str;
  986.         WriteBetween(X,X + Width,pred(Y)+depth,DTTT.KeyFCol,DTTT.BoxBCol,Str);
  987.         If DTTT.AllowSort then
  988.         begin
  989.             Fastwrite(X+4,Y+2,attr(DTTT.KeyFCol,DTTT.BoxBCol),DSortDOSStr);
  990.             Fastwrite(X+7+length(DSortDOSStr),Y+2,
  991.                       attr(DTTT.BoxFCol,DTTT.BoxBCol),
  992.                       'sort in native DOS order');
  993.             Fastwrite(X+4,Y+3,attr(DTTT.KeyFCol,DTTT.BoxBCol),DSortNameStr);
  994.             Fastwrite(X+7+length(DSortNameStr),Y+3,
  995.                       attr(DTTT.BoxFCol,DTTT.BoxBCol),
  996.                       'sort alphabetically by file Name');
  997.             Fastwrite(X+4,Y+4,attr(DTTT.KeyFCol,DTTT.BoxBCol),DSortExtStr);
  998.             Fastwrite(X+7+length(DSortExtStr),Y+4,
  999.                       attr(DTTT.BoxFCol,DTTT.BoxBCol),
  1000.                       'sort alphabetically by file Extension');
  1001.             Fastwrite(X+4,Y+5,attr(DTTT.KeyFCol,DTTT.BoxBCol),DSortSizeStr);
  1002.             Fastwrite(X+7+length(DSortSizeStr),Y+5,
  1003.                       attr(DTTT.BoxFCol,DTTT.BoxBCol),
  1004.                       'sort by file Size');
  1005.             Fastwrite(X+4,Y+6,attr(DTTT.KeyFCol,DTTT.BoxBCol),DSortTimeStr);
  1006.             Fastwrite(X+7+length(DSortTimeStr),Y+6,
  1007.                       attr(DTTT.BoxFCol,DTTT.BoxBCol),
  1008.                       'sort by date/Time of file');
  1009.             Fastwrite(X+4,Y+7,attr(DTTT.KeyFCol,DTTT.BoxBCol),DSortOrderStr);
  1010.             Fastwrite(X+7+length(DSortOrderStr),Y+7,
  1011.                       attr(DTTT.BoxFCol,DTTT.BoxBCol),
  1012.                       'sort in ascending or descending Order');
  1013.         end
  1014.         else
  1015.            WriteBetween(X,X+Width,Y+3,DTTT.BoxFCol,DTTT.BoxBCol,'SORTING DISABLED');
  1016.         If DTTT.AllowZoom then
  1017.         begin
  1018.             Fastwrite(X+4,Y+9,attr(DTTT.KeyFCol,DTTT.BoxBCol),DZoomStr);
  1019.             Fastwrite(X+7+length(DZoomStr),Y+9,
  1020.                       attr(DTTT.BoxFCol,DTTT.BoxBCol),
  1021.                       'toggle long/short box size');
  1022.         end;
  1023.         If DTTT.AllowCD then
  1024.         begin
  1025.             Fastwrite(X+4,Y+11,attr(DTTT.KeyFCol,DTTT.BoxBCol),DChangeDirStr);
  1026.             Fastwrite(X+7+length(DChangeDirStr),Y+11,
  1027.                       attr(DTTT.BoxFCol,DTTT.BoxBCol),
  1028.                       'change to new drive/directory');
  1029.             Fastwrite(X+4,Y+12,attr(DTTT.KeyFCol,DTTT.BoxBCol),DJumpParentSTr);
  1030.             Fastwrite(X+7+length(DJumpParentStr),Y+12,
  1031.                       attr(DTTT.BoxFCol,DTTT.BoxBCol),
  1032.                       'backup to parent directory');
  1033.         end;
  1034.         WriteBetween(X, X + Width, Y,
  1035.                      DTTT.BoxFCol + Blink, DTTT.BoxBCol,
  1036.                      ' press any key ... ');
  1037.  
  1038.         ChH := upcase(GetKey);
  1039.         MoveToScreen(Sc^,Mem[BaseOfScreen:0], S Div 2);
  1040.         FreeMem(Sc,S);
  1041.     end;
  1042.  
  1043.     Procedure PromptForDirectory;
  1044.     const
  1045.        width = 55;
  1046.     var
  1047.        S : word;
  1048.        Sc : pointer;
  1049.        X : byte;
  1050.        OldP,OldM,Strng : String;
  1051.     begin
  1052.         S := 160*DisplayLines;
  1053.         If MaxAvail < S then
  1054.            exit;
  1055.         OldP := Pathname;
  1056.         OldM := FileMask;
  1057.         GetMem(Sc,S);
  1058.         MoveFromScreen(Mem[BaseOfScreen:0],Sc^,S Div 2);    {SaveThescreen}
  1059.         If X1 + width > 80 then
  1060.            X := pred((80 - width) div 2)
  1061.         else
  1062.            X := X1;
  1063.         FBox(X,Y1,pred(X + width),Y1 + 2,DTTT.BoxFCol,DTTT.BoxBCol,2);
  1064.         WriteBetween(X,X+Width,Y1,DTTT.KeyFCol,DTTT.BoxBCol,'  Directory of Files  ');
  1065.         Strng := PathName+FileMask;
  1066.         Read_String_Upper(X+1,Y1+1,width - 2,'',0,Strng);
  1067.         MoveToScreen(Sc^,Mem[BaseOfScreen:0], S Div 2);
  1068.         FreeMem(Sc,S);
  1069.         If (R_Char <> #027) then
  1070.         begin
  1071.             DIRFULLFileName := Strng;
  1072.             Extract_Path_Mask;
  1073.             Release(DirTop);
  1074.             DisplayNewDirectory;
  1075.             If TotalFiles = 0 then   {re-read original directory}
  1076.             begin
  1077.                sound(800);delay(200);nosound;
  1078.                PathName := OldP;
  1079.                FileMask := OldM;
  1080.                Release(DirTop);
  1081.                DisplayNewDirectory;
  1082.             end;
  1083.         end;
  1084.     end;
  1085.  
  1086.     Function PromptForFilename(C:char):string;
  1087.     const
  1088.        width = 55;
  1089.     var
  1090.        S : word;
  1091.        Sc : pointer;
  1092.        X : byte;
  1093.        Strng : String;
  1094.        Msg : Strscreen;
  1095.     begin
  1096.         S := 160*DisplayLines;
  1097.         If MaxAvail < S then
  1098.            exit;
  1099.         GetMem(Sc,S);
  1100.         MoveFromScreen(Mem[BaseOfScreen:0],Sc^,S Div 2);    {SaveThescreen}
  1101.         If X1 + width > 80 then
  1102.            X := pred((80 - width) div 2)
  1103.         else
  1104.            X := X1;
  1105.         FBox(X,Y1,pred(X + width),Y1 + 2,DTTT.BoxFCol,DTTT.BoxBCol,2);
  1106.         If C = #0 then
  1107.         begin
  1108.            Msg := '  No files  - enter filename  ';
  1109.            Strng := '';
  1110.         end
  1111.         else
  1112.         begin
  1113.            Msg := '  Enter filename (or Esc)  ';
  1114.            Strng := C;
  1115.         end;
  1116.         WriteBetween(X,X+Width,Y1,DTTT.KeyFCol,DTTT.BoxBCol,Msg);
  1117.         Read_String_Upper(X+1,Y1+1,width-2,'',0,Strng);
  1118.         MoveToScreen(Sc^,Mem[BaseOfScreen:0], S Div 2);
  1119.         FreeMem(Sc,S);
  1120.         If (R_Char <> #027) then
  1121.             PromptForFilename := Strng
  1122.         else
  1123.             PromptForFilename := '';
  1124.     end;
  1125.  
  1126. {$ENDIF}
  1127.  
  1128. {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\}
  1129. {$IFDEF DIRFULL}
  1130.      Function No_Files_Found: integer;
  1131.      {returns 99 if user escaped
  1132.            or 0  if user enter a file
  1133.      }
  1134.      begin
  1135.  
  1136.          ChosenFile := PromptForFilename(#0);
  1137.          If ChosenFile = '' then
  1138.          begin
  1139.              No_Files_Found := 99;
  1140.              exit;
  1141.          end;
  1142.          If (pos('*',ChosenFile) > 0)
  1143.          or (pos('?',ChosenFile) > 0)
  1144.          or (ChosenFile[Length(ChosenFile)] = '\') then
  1145.          begin
  1146.              DIRFULLFileName := ChosenFile;
  1147.              Extract_Path_Mask;
  1148.              Release(DirTop);
  1149.              DisplayNewDirectory;
  1150.          end
  1151.          else
  1152.          begin
  1153.              If  (pos('\',ChosenFile) = 0)
  1154.              and (pos(':',ChosenFile) = 0) then
  1155.              begin
  1156.                  ChosenFile := PathName + ChosenFile;
  1157.                  No_Files_Found := 0;
  1158.                  exit;
  1159.              end;
  1160.          end;
  1161.          No_Files_Found := 1;
  1162.      end; {of func No_Files_Found}
  1163. {$ENDIF}
  1164.  
  1165.     Procedure Process_Keys;
  1166.     var
  1167.       ChD : char;
  1168.       Finished : Boolean;
  1169.     begin
  1170.         Finished := false;
  1171.         If TotalFiles = 0 then
  1172.         begin
  1173. {$IFDEF DIRFULL}
  1174.             Repeat
  1175.                  Case No_Files_Found of
  1176.                  0 : exit;  {user selected a file}
  1177.                  99: begin  {user escaped}
  1178.                          Retcode := NoFilesCode;
  1179.                          Exit;
  1180.                      end;
  1181.                  end; {case}
  1182.             until TotalFiles <> 0;
  1183. {$ELSE}
  1184.            Retcode := NoFilesCode;
  1185.            WriteAt(succ(X1),succ(Y2),DTTT.DirFCol,DTTT.BoxBCol,       {5.01}
  1186.            'No files found.... press any key');
  1187.            ChD := GetKey;
  1188.            Exit;
  1189. {$ENDIF}
  1190.         end;
  1191.         Repeat
  1192.              ChD := upcase(GetKey);
  1193.              Case ChD of
  1194.              #129,                  {mouse down, down arrow}
  1195.              #208 :  If not BottomLine then
  1196.                      begin
  1197.                          LoLightFile(HiFn);
  1198.                          Hifn := HiFn + Columnswide;
  1199.                          If HiFn <= BotFn then
  1200.                             HiLightFile(HiFn)
  1201.                          else
  1202.                             Scroll_Down;
  1203.                      end;
  1204.              #128,                      {mouse up, up arrow}
  1205.              #200 : If not TopLine then
  1206.                     begin
  1207.                         LoLightFile(HiFn);
  1208.                         Hifn := HiFn - Columnswide;
  1209.                         If HiFn >= TopFn then
  1210.                            HiLightFile(HiFn)
  1211.                         else
  1212.                            Scroll_Up;
  1213.                     end;
  1214.              #205 : If HiFn < TotalFiles then  {right arrow}
  1215.                     begin
  1216.                         LolightFile(HiFn);
  1217.                         Inc(HiFn);
  1218.                         If HiFn > BotFn then
  1219.                            Scroll_Down
  1220.                         else
  1221.                            HiLightFile(HiFn);
  1222.                     end;
  1223.              #131 : If  (LastColumn = false) and (HiFn < BotFn) then  {mouse right}
  1224.                     begin
  1225.                         LolightFile(HiFn);
  1226.                         Inc(HiFn);
  1227.                         HiLightFile(HiFn);
  1228.                     end;
  1229.              #130 : If (FirstColumn = false) then   {mouse left}
  1230.                     begin
  1231.                        LolightFile(HiFn);
  1232.                        Dec(HiFn);
  1233.                        HiLightFile(HiFn);
  1234.                     end;
  1235.              #203 : If HiFn > 1 then {Left arrow}
  1236.                     begin
  1237.                         LolightFile(HiFn);
  1238.                         Dec(HiFn);
  1239.                         If HiFn < TopFn then
  1240.                            Scroll_Up
  1241.                         else
  1242.                            HiLightFile(HiFn);
  1243.                     end;
  1244.              #199 : If Columnswide = 1 then
  1245.                     begin
  1246.                         If TopFn = 1 then
  1247.                         begin
  1248.                             LoLightFile(HiFn);
  1249.                             HiFn := 1;
  1250.                              HiLightFile(HiFn);
  1251.                         end
  1252.                         else
  1253.                            Scroll_Top;
  1254.                     end
  1255.                     else  {multiple column}
  1256.                     begin
  1257.                         If not FirstColumn then   {home}
  1258.                         begin
  1259.                             LoLightFile(HiFn);
  1260.                             HiFn := HiFn - (pred(HiFn) mod ColumnsWide);
  1261.                             HiLightFile(HiFn);
  1262.                         end;
  1263.                     end;
  1264.              #207 : If ColumnsWide = 1  then   {end}
  1265.                     begin
  1266.                         If TotalFiles <= BotFn then
  1267.                         begin
  1268.                              LoLightFile(HiFn);
  1269.                              HiFn := TotalFiles;
  1270.                              HiLightFile(HiFn);
  1271.                         end
  1272.                         else
  1273.                            Scroll_Bottom;
  1274.                     end
  1275.                     else
  1276.                     begin
  1277.                         If not LastColumn then
  1278.                         begin
  1279.                             LoLightFile(HiFn);
  1280.                             HiFn := HiFn
  1281.                                   + Columnswide
  1282.                                   - HiFn mod ColumnsWide;
  1283.                             If HiFn > BotFn then
  1284.                                HiFn := BotFn;
  1285.                             HiLightFile(HiFn);
  1286.                         end;
  1287.                     end;
  1288.              #245 : If HiFn < TotalFiles then      {Ctrl End}
  1289.                     begin
  1290.                         If BotFn = TotalFiles then
  1291.                         begin
  1292.                              LoLightFile(HiFn);
  1293.                              HiFn := TotalFiles;
  1294.                              HiLightFile(HiFn);
  1295.                         end
  1296.                         else
  1297.                         begin
  1298.                            BotFn := TotalFiles;
  1299.                            RecalcTopFn;
  1300.                            HiFn := TotalFiles;
  1301.                            DisplayFiles;
  1302.                         end;
  1303.                     end;
  1304.              #201 : If HiFn > 1 then               {PgUp}
  1305.                     begin
  1306.                         If TopFn > 1 then
  1307.                         begin
  1308.                             TopFn := TopFn - R*ColumnsWide;
  1309.                             If TopFn < 1 then
  1310.                                TopFn := 1;
  1311.                         end;
  1312.                         RecalcBotFn;
  1313.                         HiFN := HiFn - R*ColumnsWide;
  1314.                         If HiFn < 1 then
  1315.                            HiFn := 1;
  1316.                         DisplayFiles;
  1317.                     end;
  1318.              #209 : If Hifn < TotalFiles then      {PgDn}
  1319.                     begin
  1320.                         If BotFn < TotalFiles then
  1321.                         begin
  1322.                             TopFn := TopFN + R*ColumnsWide;
  1323.                             BotFn := BotFn + R*ColumnsWide;
  1324.                             HiFn := HiFn + R*ColumnsWide;
  1325.                             If BotFn > TotalFiles then
  1326.                             begin
  1327.                                 BotFn := TotalFiles;
  1328.                                 RecalcTopFn;
  1329.                                 If  (HiFn < TopFn) then
  1330.                                     Repeat
  1331.                                         HiFn := HiFn + ColumnsWide;
  1332.                                     Until HiFN >= TopFN
  1333.                                 else
  1334.                                     If (HiFn > BotFn)  then
  1335.                                         HiFn := BotFn;
  1336.                             end;
  1337.                             DisplayFiles;
  1338.                         end
  1339.                         else     {Botfn is last file}
  1340.                         begin
  1341.                             LoLightFile(HiFn);
  1342.                             If BottomLine then
  1343.                                 HiFn := BotFn
  1344.                             else
  1345.                                 HiFn := HiFn + R*ColumnsWide;
  1346.                             If HiFn > BotFn then
  1347.                                HiFn := BotFn;
  1348.                             HiLightFile(HiFn);
  1349.                         end;
  1350.                     end;
  1351.              #247 : If HiFn > 1 then      {Ctrl Home}
  1352.                     begin
  1353.                         If TopFn = 1 then
  1354.                         begin
  1355.                              LoLightFile(HiFn);
  1356.                              HiFn := 1;
  1357.                              HiLightFile(HiFn);
  1358.                         end
  1359.                         else
  1360.                            Scroll_Top;
  1361.                     end;
  1362.        DTogglekey : If DTTT.AllowToggle then
  1363.                     begin
  1364.                         ShowingDetails := not ShowingDetails;
  1365.                         If Not ShowingDetails then
  1366.                            ColumnsWide := DTTT.ColsWide
  1367.                         else
  1368.                            Columnswide := 1;
  1369.                         MoveToScreen(Scrn^,mem[BaseofScreen:0],80*DisplayLines);
  1370.                         Calculate_Box_Dimensions;
  1371.                         If Zoomed then
  1372.                         begin
  1373.                             Y3 := DTTT.Zoomline;
  1374.                             R := pred(Y3 - Y2);
  1375.                         end;
  1376.                         TopFn := 0;
  1377.                         Repeat
  1378.                             If TopFN = 0 then
  1379.                                TopFn := 1
  1380.                             else
  1381.                                TopFn := TopFN + R*ColumnsWide;
  1382.                             BotFn := pred( TopFn + ColumnsWide*R);
  1383.                             If BotFn > TotalFiles then
  1384.                             begin
  1385.                                BotFn := TotalFiles;
  1386.                                If BotFn - pred(R*ColumnsWide) > 0 then
  1387.                                   TopFn := BotFN - pred(R*ColumnsWide);
  1388.                             end;
  1389.                         until ((HiFn >= TopFn) and (HiFn <= BotFn));
  1390.                         Display_Box;
  1391.                         FillInfo;
  1392.                         DisplayFiles;
  1393.                     end;
  1394. {$IFDEF DIRFULL}
  1395.          DZoomKey : If DTTT.AllowZoom then
  1396.                     begin
  1397.                         If Zoomed then
  1398.                         begin
  1399.                            MoveToScreen(Scrn^,mem[BaseofScreen:0],80*DisplayLines);
  1400.                             Zoomed := false;
  1401.                             Y3 := Y3_Unzoomed;
  1402.                             R := pred(Y3 - Y2);
  1403.                             RecalcBotFn;
  1404.                             If HiFn > BotFn then
  1405.                                HiFn := BotFn;
  1406.                             Display_Box;
  1407.                             FillInfo;
  1408.                             DisplayFiles;
  1409.                         end
  1410.                         else
  1411.                         begin
  1412.                             If (DTTT.ZoomLine > Y3) and (DTTT.ZoomLine <= DisplayLines) then
  1413.                             begin
  1414.                                 MoveToScreen(Scrn^,mem[BaseofScreen:0],80*DisplayLines);
  1415.                                 Zoomed := true;
  1416.                                 Y3 := DTTT.ZoomLine;
  1417.                                 R := pred(Y3 - Y2);
  1418.                                 RecalcBotFn;
  1419.                                 Display_Box;
  1420.                                 FillInfo;
  1421.                                 DisplayFiles;
  1422.                             end;
  1423.                         end;
  1424.                     end;
  1425.     DSortOrderKey : If DTTT.AllowSort then
  1426.                     begin
  1427.                         SortAsc := not SortAsc;
  1428.                         TopFn := 1;
  1429.                         HiFn := 1;
  1430.                         RecalcBotFn;
  1431.                         DisplayFiles;
  1432.                     end;
  1433.     DSortNameKey  : If DTTT.AllowSort and (SortOrder <> DSortName) then
  1434.                     begin
  1435.                         SortOrder := DSortName;
  1436.                         ReSort;
  1437.                     end;
  1438.     DSortExtKey   : If DTTT.AllowSort and (SortOrder <> DSortExt) then
  1439.                     begin
  1440.                         SortOrder := DSortExt;
  1441.                         ReSort;
  1442.                     end;
  1443.     DSortSizeKey  : If DTTT.AllowSort and (SortOrder <> DSortSize) then
  1444.                     begin
  1445.                         SortOrder := DSortSize;
  1446.                         ReSort;
  1447.                     end;
  1448.     DSortTimeKey  : If DTTT.AllowSort and (SortOrder <> DSortTime) then
  1449.                     begin
  1450.                         SortOrder := DSortTime;
  1451.                         ReSort;
  1452.                     end;
  1453.     DSortDOSKey   : If DTTT.AllowSort and (SortOrder <> DSortDOS) then
  1454.                     begin
  1455.                         SortOrder := DSortDOS;
  1456.                         ReSort;
  1457.                     end;
  1458.     DHelpKey      : If DTTT.AllowHelp then
  1459.                        ShowHelpScreen;
  1460.     DJumpParentKey: If DTTT.AllowCD and (length(PathName) > 3) then  {Enter}
  1461.                     begin
  1462.                         PathName := PathParent(PathName);
  1463.                         Release(DirTop);
  1464.                         DisplayNewDirectory;
  1465.                     end;
  1466.     DChangeDirKey : If DTTT.AllowCD then
  1467.                        PromptForDirectory;
  1468.     #33..#126     :  If DTTT.AllowInput then
  1469.                      begin               {user entered an alpha numeric}
  1470.                          ChosenFile := PromptForFilename(ChD);
  1471.                          If ChosenFile <> '' then
  1472.                          begin
  1473.                              If (ChosenFile[Length(ChosenFile)] = ':') then
  1474.                                  ChosenFile := ChosenFile +'*.*';
  1475.                              If (pos('*',ChosenFile) > 0)
  1476.                              or (pos('?',ChosenFile) > 0)
  1477.                              or (ChosenFile[Length(ChosenFile)] = '\') then
  1478.                              begin
  1479.                                  DIRFULLFileName := ChosenFile;
  1480.                                  Extract_Path_Mask;
  1481.                                  Release(DirTop);
  1482.                                  DisplayNewDirectory;
  1483.                              end
  1484.                              else
  1485.                              begin
  1486.                                 If (pos('\',ChosenFile) = 0)
  1487.                                 and (pos(':',ChosenFile) = 0) then
  1488.                                     ChosenFile := PathName + ChosenFile;
  1489.                                 Finished := true;
  1490.                              end;
  1491.                          end;
  1492.                      end;
  1493. {$ENDIF}
  1494.              #133,                                                 {Mouse left}
  1495.              #13  : If SubDirectory(FilePointer(HiFn)^.Attr) then  {Enter}
  1496.                     begin
  1497.                         If File_Name(HiFn) = '..' then
  1498.                            PathName := PathParent(PathName)
  1499.                         else
  1500.                            PathName := PathChild(File_Name(HiFn));
  1501.                         If (DTTT.SelectDir = false) then
  1502.                         begin
  1503.                            Release(DirTop);
  1504.                            DisplayNewDirectory;
  1505.                         end
  1506.                         else                      {return the Directory}
  1507.                         begin
  1508.                             Finished := true;
  1509.                             ChosenFile := PathNoSlash(PathName);
  1510.                         end;
  1511.                     end
  1512.                     else
  1513.                     begin
  1514.                         Finished := true;
  1515.                         ChosenFile := PathName+File_Name(HiFn);
  1516.                     end;
  1517.              #132,                          {mouse right}
  1518.              #027 : begin                   {esc}
  1519.                         Finished := true;
  1520.                         Retcode := EscCode;
  1521.                         ChosenFile := '';
  1522.                     end;
  1523.              end;  {case}
  1524.              If TotalFiles = 0 then
  1525.              begin
  1526.        {$IFDEF DIRFULL}
  1527.                    Repeat
  1528.                       Case No_Files_Found of
  1529.                       0 : exit;  {user selected a file}
  1530.                       99: begin  {user escaped}
  1531.                                Retcode := NoFilesCode;
  1532.                                Exit;
  1533.                             end;
  1534.                       end; {case}
  1535.                    until TotalFiles <> 0;
  1536.        {$ELSE}
  1537.                 Retcode := NoFilesCode;
  1538.                 Exit;
  1539.        {$ENDIF}
  1540.              end;
  1541.         Until Finished;
  1542.     end; {sub proc Process_Keys}
  1543.  
  1544.     Procedure SaveInitScreen;
  1545.     var S : word;
  1546.     begin
  1547.         S := 160*DisplayLines;
  1548.         If MaxAvail < S then
  1549.            NoMemory := true
  1550.         else
  1551.         begin
  1552.             Getmem(Scrn,160*DisplayLines);
  1553.             MoveFromScreen(Mem[BaseOfScreen:0],Scrn^,S div 2);
  1554.             FindCursor(CursRec[1],Cursrec[2],Cursrec[3],Cursrec[4]);
  1555.             OffCursor;
  1556.         end;
  1557.     end;
  1558.  
  1559.     Procedure Clear;
  1560.     begin
  1561.         If DTTT.RestoreScreen then
  1562.             MoveToScreen(Scrn^,mem[BaseofScreen:0],80*DisplayLines);
  1563.         PosCursor(Cursrec[1],Cursrec[2]);
  1564.         SizeCursor(Cursrec[3],Cursrec[4]);
  1565.         Release(HeapTop);
  1566.     end;
  1567.  
  1568. begin          {main procedure}
  1569.     Mark(HeapTop);
  1570.     NoMemory := False;
  1571.     Zoomed := False;
  1572.     ShowingDetails := DTTT.ShowDetails;
  1573.     SortAsc := DTTT.Asc = 1;
  1574.     SortOrder := DTTT.InitSort;
  1575.     If Not ShowingDetails then
  1576.        ColumnsWide := DTTT.ColsWide
  1577.     else
  1578.        Columnswide := 1;
  1579.     SaveInitScreen;
  1580.     If NoMemory then
  1581.     begin
  1582.         Retcode := Memcode;
  1583.         exit;
  1584.     end;
  1585.     {$I-}
  1586.     GetDir(0,StartDir);
  1587.     {SI+}
  1588.     If IOResult <> 0 then
  1589.     begin
  1590.         Retcode := UnknownCode;
  1591.         exit;
  1592.     end;
  1593.     Retcode := OKCode;     {assume it will succeed!}
  1594.     Extract_Path_Mask;
  1595.     Calculate_Box_Dimensions;
  1596.     Y3_unzoomed := Y3;   {ugh?}
  1597.     DisplayNewDirectory;
  1598.     If NoMemory then
  1599.     begin
  1600.        Clear;
  1601.        Retcode := Memcode;
  1602.     end
  1603.     else
  1604.        Process_Keys;
  1605.     Clear;
  1606.     Display_Directory := ChosenFile;
  1607. end;
  1608.  
  1609. begin
  1610.     Default_Settings;
  1611.     Horiz_Sensitivity := 3;
  1612. end.
  1613.